#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <syserr.h>
#include <fcntl.h>
#include <unistd.h>
#include <device.h>
#include <utils.h>
#include <time.h>
#include <sys/time.h>
#include "printk.h"
#include "chn.h"

/*
 * uart
 */
#if defined(AT9260) || defined(NUC970)

#define UART_NR 11

int __weak hw_register_uart(void)
{
    int i;

    for (i = 0; i < UART_NR; i++)
    {
        char name[OBJECT_NAME_SIZE];
        snprintf(name, sizeof(name), "uart%d", i);

        uart_dev_add(name, NULL);
    }
    return 0;
}
struct app_dev_map
{
    int chn_no, uart_no;
};
static const struct app_dev_map app_dev_maps[] =
{
#ifdef AT9260
    {CHN_DBG,       0},
    {CHN_ESAM,      6},
    {CHN_GPRS,      1},
    {CHN_485I,      2},
    {CHN_485II,     3},
    {CHN_485III,    9},
    {CHN_INF,       5},
    {CHN_RT,        4},
    {CHN_AC,        -1},
#elif defined NUC970
    {CHN_DBG,       9},
    {CHN_ESAM,      -1},
    {CHN_GPRS,      1},
    {CHN_485I,      4},
    {CHN_485II,     6},
    {CHN_485III,    -1},
    {CHN_INF,       8},
    {CHN_RT,        2},
    {CHN_AC,        10},
#endif
};
int get_uart_no_by_chn(int chnno)
{
    int i;

    for (i = 0; i < array_size(app_dev_maps); i++)
    {
        if (app_dev_maps[i].chn_no == chnno)
            return app_dev_maps[i].uart_no;
    }
    return -1;
}
const char *get_uart_name_by_chn(int chnno)
{
    static char devname[OBJECT_NAME_SIZE];

    int uartno = get_uart_no_by_chn(chnno);
    if (uartno < 0)
        return NULL;

    snprintf(devname, sizeof(devname), "uart%d", uartno);
    return devname;
}
#endif

/*
 * time
 */
#if defined NUC970 || defined AT9260
static int _rx8025_fd = -1;
void get_cur_bcd_time(u8 *bcdtm)
{
    if (_rx8025_fd < 0)
        _rx8025_fd = open("/dev/VIIC0", O_RDWR);

    assert(_rx8025_fd >= 0);
    read(_rx8025_fd, bcdtm, 6);
}
int board_gettimeofday(struct timeval *tv, struct timezone *tz)
{
    u8 bcdtm[6];

    get_cur_bcd_time(bcdtm);

    struct tm t;
    t.tm_year = bcd2bin(bcdtm[5]) + 2000 - 1900;
    t.tm_mon  = bcd2bin(bcdtm[4]) - 1;
    t.tm_mday = bcd2bin(bcdtm[3]);
    t.tm_hour = bcd2bin(bcdtm[2]);
    t.tm_min  = bcd2bin(bcdtm[1]);
    t.tm_sec  = bcd2bin(bcdtm[0]);
    t.tm_isdst = -1;
    tv->tv_sec = mktime(&t);
    tv->tv_usec = 0;
    return 0;
}
#else
void get_cur_bcd_time(u8 *bcdtm)
{
    int i;
    time_t now;
    struct tm *tm_now;

    time(&now);
    tm_now = localtime(&now);

    bcdtm[0] = tm_now->tm_sec;
    bcdtm[1] = tm_now->tm_min;
    bcdtm[2] = tm_now->tm_hour;
    bcdtm[3] = tm_now->tm_mday;
    bcdtm[4] = tm_now->tm_mon + 1;
    bcdtm[5] = tm_now->tm_year - 100;

    for (i = 0; i < 6; i++)
        bcdtm[i] = bin2bcd(bcdtm[i]);
}
int board_gettimeofday(struct timeval *tv, struct timezone *tz)
{
    return gettimeofday(tv, tz);
}
#endif
